///*
// *                    BioJava development code
// *
// * This code may be freely distributed and modified under the
// * terms of the GNU Lesser General Public Licence.  This should
// * be distributed with the code.  If you do not have a copy,
// * see:
// *
// *      http://www.gnu.org/copyleft/lesser.html
// *
// * Copyright for this code is held jointly by the individual
// * authors.  These should be listed in @author doc comments.
// *
// * For more information on the BioJava project and its aims,
// * or to join the biojava-l mailing list, visit the home page
// * at:
// *
// *      http://www.biojava.org/
// *
// * Created on June 7, 2010
// * Author: Mark Chapman
// */
//
//package org.jscc.app.client.biojava3.alignment;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.concurrent.ExecutionException;
//import java.util.concurrent.Future;
//
//import org.jscc.app.client.biojava3.alignment.template.*;
//import org.jscc.app.client.biojava3.core.sequence.template.Compound;
//import org.jscc.app.client.biojava3.core.sequence.template.Sequence;
////import org.jscc.app.client.biojava3.core.util.ConcurrencyTools;
//
///**
// * Static utility to easily run alignment routines.  To exit cleanly after running any parallel method that mentions
// * use of the {@link ConcurrencyTools} utility, {@link ConcurrencyTools#shutdown()} or
// * {@link ConcurrencyTools#shutdownAndAwaitTermination()} must be called.
// *
// * @author Mark Chapman
// */
//public class Alignments {
//
//    /**
//     * List of multiple sequence alignment routines that can (mostly) be emulated.
//     */
//    public static enum MSAEmulation {
//                   // PairwiseScorer     Cluster  ProfileAligner       GapPenalty  Refinement
//        CLUSTAL,   // KMERS              UPGMA    GLOBAL_CONSENSUS     Standard
//        CLUSTALW,  // GLOBAL_IDENTITIES  NJ       GLOBAL_LINEAR_SPACE  Variable
//        CLUSTALW2, // GLOBAL_IDENTITIES  NJ       GLOBAL_LINEAR_SPACE  Variable    PARTITION_SINGLE(ALL)
//        MUSCLE,    // KMERS              UPGMA    GLOBAL               Variable    RESCORE_IDENTITIES/PARTITION_TREE
//        KALIGN     // WU_MANBER          UPGMA    GLOBAL               Standard
//    }
//
//    /**
//     * List of implemented pairwise sequence alignment routines.
//     */
//    public static enum PairwiseAligner {
//        GLOBAL,
//        GLOBAL_LINEAR_SPACE,
//        LOCAL,
//        LOCAL_LINEAR_SPACE
//    }
//
//    /**
//     * List of implemented pairwise sequence scoring routines.
//     */
//    public static enum PairwiseScorer {
//        GLOBAL,
//        GLOBAL_IDENTITIES,
//        GLOBAL_SIMILARITIES,
//        LOCAL,
//        LOCAL_IDENTITIES,
//        LOCAL_SIMILARITIES,
//        KMERS,
//        WU_MANBER
//    }
//
//    /**
//     * List of implemented profile-profile alignment routines.
//     */
//    public static enum ProfileAligner {
//        GLOBAL,
//        GLOBAL_LINEAR_SPACE,
//        GLOBAL_CONSENSUS,
//        LOCAL,
//        LOCAL_LINEAR_SPACE,
//        LOCAL_CONSENSUS
//    }
//
//    /**
//     * List of implemented profile refinement routines.
//     */
//    public static enum Refinement {
//        PARTITION_SINGLE,
//        PARTITION_SINGLE_ALL,
//        PARTITION_TREE,
//        PARTITION_TREE_ALL,
//        RESCORE_IDENTITIES,
//        RESCORE_SIMILARITIES
//    }
//
//    // prevents instantiation
//    private Alignments() { }
//
//    // public factory methods
//
//    /**
//     * Factory method which computes a sequence alignment for all {@link Sequence} pairs in the given {@link List}.
//     * This method runs the alignments in parallel by submitting all of the alignments to the shared thread pool of the
//     * {@link ConcurrencyTools} utility.
//     *
//     * @param <S> each {@link Sequence} of an alignment pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param sequences the {@link List} of {@link Sequence}s to align
//     * @param type chosen type from list of pairwise sequence alignment routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return list of sequence alignment pairs
//     */
//    public static <S extends Sequence<C>, C extends Compound> List<SequencePair<S, C>> getAllPairsAlignments(
//            List<S> sequences, PairwiseAligner type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        return runPairwiseAligners(getAllPairsAligners(sequences, type, gapPenalty, subMatrix));
//    }
//
//    /**
//     * Factory method which computes a multiple sequence alignment for the given {@link List} of {@link Sequence}s.
//     *
//     * @param <S> each {@link Sequence} of the {@link List} is of type S
//     * @param <C> each element of a {@link Sequence} is a {@link Compound} of type C
//     * @param sequences the {@link List} of {@link Sequence}s to align
//     * @param type chosen type from list of multiple sequence alignment routines
//     * @param settings optional settings that adjust the alignment
//     * @return multiple sequence alignment {@link Profile}
//     */
//    public static <S extends Sequence<C>, C extends Compound> Profile<S, C> getMultipleSequenceAlignment(
//            List<S> sequences, MSAEmulation type, Object... settings) {
//        // TODO MSA emulation, convert other factories to this parameter style?
//        PairwiseScorer ps = PairwiseScorer.GLOBAL_IDENTITIES;
//        GapPenalty gapPenalty = new SimpleGapPenalty();
//        SubstitutionMatrix<C> subMatrix = new SimpleSubstitutionMatrix<C>();
//        ProfileAligner pa = ProfileAligner.GLOBAL;
//        for (Object o : settings) {
//            if (o instanceof PairwiseScorer) {
//                ps = (PairwiseScorer) o;
//            } else if (o instanceof GapPenalty) {
//                gapPenalty = (GapPenalty) o;
//            } else if (o instanceof SubstitutionMatrix<?>) {
//                subMatrix = (SubstitutionMatrix<C>) o;
//            } else if (o instanceof ProfileAligner) {
//                pa = (ProfileAligner) o;
//            }
//        }
//
//        // stage 1: pairwise similarity calculation
//        List<PairwiseSequenceScorer<S, C>> scorers = getAllPairsScorers(sequences, ps, gapPenalty, subMatrix);
//        runPairwiseScorers(scorers);
//
//        // stage 2: hierarchical clustering into a guide tree
//        GuideTree<S, C> tree = new GuideTree<S, C>(sequences, scorers);
//
//        // stage 3: progressive alignment
//        Profile<S, C> msa = getProgressiveAlignment(tree, pa, gapPenalty, subMatrix);
//
//        // stage 4: TODO refinement
//        return msa;
//    }
//
//    /**
//     * Factory method which computes a sequence alignment for the given {@link Sequence} pair.
//     *
//     * @param <S> each {@link Sequence} of the pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param query the first {@link Sequence}s to align
//     * @param target the second {@link Sequence}s to align
//     * @param type chosen type from list of pairwise sequence alignment routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return sequence alignment pair
//     */
//    public static <S extends Sequence<C>, C extends Compound> SequencePair<S, C> getPairwiseAlignment(
//            S query, S target, PairwiseAligner type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        return getPairwiseAligner(query, target, type, gapPenalty, subMatrix).getPair();
//    }
//
//    // default access (package private) factory methods
//
//    /**
//     * Factory method which sets up a sequence alignment for all {@link Sequence} pairs in the given {@link List}.
//     *
//     * @param <S> each {@link Sequence} of an alignment pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param sequences the {@link List} of {@link Sequence}s to align
//     * @param type chosen type from list of pairwise sequence alignment routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return list of pairwise sequence aligners
//     */
//    static <S extends Sequence<C>, C extends Compound> List<PairwiseSequenceAligner<S, C>> getAllPairsAligners(
//            List<S> sequences, PairwiseAligner type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        List<PairwiseSequenceAligner<S, C>> allPairs = new ArrayList<PairwiseSequenceAligner<S, C>>();
//        for (int i = 0; i < sequences.size(); i++) {
//            for (int j = i+1; j < sequences.size(); j++) {
//                allPairs.add(getPairwiseAligner(sequences.get(i), sequences.get(j), type, gapPenalty, subMatrix));
//            }
//        }
//        return allPairs;
//    }
//
//    /**
//     * Factory method which sets up a sequence pair scorer for all {@link Sequence} pairs in the given {@link List}.
//     *
//     * @param <S> each {@link Sequence} of a pair is of type S
//     * @param <C> each element of a {@link Sequence} is a {@link Compound} of type C
//     * @param sequences the {@link List} of {@link Sequence}s to align
//     * @param type chosen type from list of pairwise sequence scoring routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return list of sequence pair scorers
//     */
//    static <S extends Sequence<C>, C extends Compound> List<PairwiseSequenceScorer<S, C>> getAllPairsScorers(
//            List<S> sequences, PairwiseScorer type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        List<PairwiseSequenceScorer<S, C>> allPairs = new ArrayList<PairwiseSequenceScorer<S, C>>();
//        for (int i = 0; i < sequences.size(); i++) {
//            for (int j = i+1; j < sequences.size(); j++) {
//                allPairs.add(getPairwiseScorer(sequences.get(i), sequences.get(j), type, gapPenalty, subMatrix));
//            }
//        }
//        return allPairs;
//    }
//
//    /**
//     * Factory method which computes a sequence pair score for all {@link Sequence} pairs in the given {@link List}.
//     * This method runs the scorings in parallel by submitting all of the scorings to the shared thread pool of the
//     * {@link ConcurrencyTools} utility.
//     *
//     * @param <S> each {@link Sequence} of a pair is of type S
//     * @param <C> each element of a {@link Sequence} is a {@link Compound} of type C
//     * @param sequences the {@link List} of {@link Sequence}s to align
//     * @param type chosen type from list of pairwise sequence scoring routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return list of sequence pair scores
//     */
//    static <S extends Sequence<C>, C extends Compound> int[] getAllPairsScores(
//            List<S> sequences, PairwiseScorer type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        return runPairwiseScorers(getAllPairsScorers(sequences, type, gapPenalty, subMatrix));
//    }
//
//    /**
//     * Factory method which computes a similarity score for the given {@link Sequence} pair.
//     *
//     * @param <S> each {@link Sequence} of the pair is of type S
//     * @param <C> each element of a {@link Sequence} is a {@link Compound} of type C
//     * @param query the first {@link Sequence} to score
//     * @param target the second {@link Sequence} to score
//     * @param type chosen type from list of pairwise sequence scoring routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return sequence pair score
//     */
//    static <S extends Sequence<C>, C extends Compound> int getPairwiseScore(
//            S query, S target, PairwiseScorer type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        return getPairwiseScorer(query, target, type, gapPenalty, subMatrix).getScore();
//    }
//
//    /**
//     * Factory method which computes a profile alignment for the given {@link Profile} pair.
//     *
//     * @param <S> each {@link Sequence} of the {@link Profile} pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param profile1 the first {@link Profile} to align
//     * @param profile2 the second {@link Profile} to align
//     * @param type chosen type from list of profile-profile alignment routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return alignment profile
//     */
//    static <S extends Sequence<C>, C extends Compound> ProfilePair<S, C> getProfileProfileAlignment(
//            Profile<S, C> profile1, Profile<S, C> profile2, ProfileAligner type, GapPenalty gapPenalty,
//            SubstitutionMatrix<C> subMatrix) {
//        return getProfileProfileAligner(profile1, profile2, type, gapPenalty, subMatrix).getPair();
//    }
//
//    /**
//     * Factory method to run the profile-profile alignments of a progressive multiple sequence alignment concurrently.
//     * This method runs the alignments in parallel by submitting all of the alignment tasks to the shared thread pool
//     * of the {@link ConcurrencyTools} utility.
//     *
//     * @param <S> each {@link Sequence} of the {@link Profile} pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param tree guide tree to follow aligning profiles from leaves to root
//     * @param type chosen type from list of profile-profile alignment routines
//     * @param gapPenalty the gap penalties used during alignment
//     * @param subMatrix the set of substitution scores used during alignment
//     * @return multiple sequence alignment
//     */
//    static <S extends Sequence<C>, C extends Compound> Profile<S, C> getProgressiveAlignment(
//            GuideTree<S, C> tree, ProfileAligner type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//
//        // find inner nodes in post-order traversal of tree (each leaf node has a single sequence profile)
//        List<GuideTreeNode<S, C>> innerNodes = new ArrayList<GuideTreeNode<S, C>>();
//        for (GuideTreeNode<S, C> n : tree) {
//            if (n.getProfile() == null) {
//                innerNodes.add(n);
//            }
//        }
//
//        // submit alignment tasks to the shared thread pool
//        int i = 1, all = innerNodes.size();
//        for (GuideTreeNode<S, C> n : innerNodes) {
//            Profile<S, C> p1 = n.getChild1().getProfile(), p2 = n.getChild2().getProfile();
//            Future<ProfilePair<S, C>> pf1 = n.getChild1().getProfileFuture(), pf2 = n.getChild2().getProfileFuture();
//            ProfileProfileAligner<S, C> aligner =
//                    (p1 != null) ? ((p2 != null) ? getProfileProfileAligner(p1, p2, type, gapPenalty, subMatrix) :
//                            getProfileProfileAligner(p1, pf2, type, gapPenalty, subMatrix)) :
//                    ((p2 != null) ? getProfileProfileAligner(pf1, p2, type, gapPenalty, subMatrix) :
//                            getProfileProfileAligner(pf1, pf2, type, gapPenalty, subMatrix));
//            n.setProfileFuture(ConcurrencyTools.submit(new CallableProfileProfileAligner<S, C>(aligner), String.format(
//                    "Aligning pair %d of %d", i++, all)));
//        }
//
//        // retrieve the alignment results
//        for (GuideTreeNode<S, C> n : innerNodes) {
//            // TODO when added to ConcurrencyTools, log completions and exceptions instead of printing stack traces
//            try {
//                n.setProfile(n.getProfileFuture().get());
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            } catch (ExecutionException e) {
//                e.printStackTrace();
//            }
//        }
//
//        // the alignment profile at the root of the tree is the full multiple sequence alignment
//        return tree.getRoot().getProfile();
//    }
//
//    /**
//     * Factory method to run a list of alignments concurrently.  This method runs the alignments in parallel by
//     * submitting all of the alignment tasks to the shared thread pool of the {@link ConcurrencyTools} utility.
//     *
//     * @param <S> each {@link Sequence} of an alignment pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param aligners list of alignments to run
//     * @return list of {@link SequencePair} results from running alignments
//     */
//    static <S extends Sequence<C>, C extends Compound> List<SequencePair<S, C>>
//            runPairwiseAligners(List<PairwiseSequenceAligner<S, C>> aligners) {
//        int n = 1, all = aligners.size();
//        List<Future<SequencePair<S, C>>> futures = new ArrayList<Future<SequencePair<S, C>>>();
//        for (PairwiseSequenceAligner<S, C> aligner : aligners) {
//            futures.add(ConcurrencyTools.submit(new CallablePairwiseSequenceAligner<S, C>(aligner),
//                    String.format("Aligning pair %d of %d", n++, all)));
//        }
//        return getListFromFutures(futures);
//    }
//
//    /**
//     * Factory method to run a list of scorers concurrently.  This method runs the scorers in parallel by submitting
//     * all of the scoring tasks to the shared thread pool of the {@link ConcurrencyTools} utility.
//     *
//     * @param <S> each {@link Sequence} of an alignment pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param scorers list of scorers to run
//     * @return list of score results from running scorers
//     */
//    static <S extends Sequence<C>, C extends Compound> int[] runPairwiseScorers(
//            List<PairwiseSequenceScorer<S, C>> scorers) {
//        int n = 1, all = scorers.size();
//        List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
//        for (PairwiseSequenceScorer<S, C> scorer : scorers) {
//            futures.add(ConcurrencyTools.submit(new CallablePairwiseSequenceScorer<S, C>(scorer),
//                    String.format("Scoring pair %d of %d", n++, all)));
//        }
//        List<Integer> results = getListFromFutures(futures);
//        int[] scores = new int[results.size()];
//        for (int i = 0; i < scores.length; i++) {
//            scores[i] = results.get(i);
//        }
//        return scores;
//    }
//
//    /**
//     * Factory method to run a list of alignments concurrently.  This method runs the alignments in parallel by
//     * submitting all of the alignment tasks to the shared thread pool of the {@link ConcurrencyTools} utility.
//     *
//     * @param <S> each {@link Sequence} of the {@link Profile} pair is of type S
//     * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
//     * @param aligners list of alignments to run
//     * @return list of {@link ProfilePair} results from running alignments
//     */
//    static <S extends Sequence<C>, C extends Compound> List<ProfilePair<S, C>>
//            runProfileAligners(List<ProfileProfileAligner<S, C>> aligners) {
//        int n = 1, all = aligners.size();
//        List<Future<ProfilePair<S, C>>> futures = new ArrayList<Future<ProfilePair<S, C>>>();
//        for (ProfileProfileAligner<S, C> aligner : aligners) {
//            futures.add(ConcurrencyTools.submit(new CallableProfileProfileAligner<S, C>(aligner),
//                    String.format("Aligning pair %d of %d", n++, all)));
//        }
//        return getListFromFutures(futures);
//    }
//
//    // helper methods
//
//    // retrieves calculated elements from a list on the concurrent execution queue
//    private static <E> List<E> getListFromFutures(List<Future<E>> futures) {
//        List<E> list = new ArrayList<E>();
//        for (Future<E> f : futures) {
//            // TODO when added to ConcurrencyTools, log completions and exceptions instead of printing stack traces
//            try {
//                list.add(f.get());
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            } catch (ExecutionException e) {
//                e.printStackTrace();
//            }
//        }
//        return list;
//    }
//
//    // constructs a pairwise sequence aligner
//    private static <S extends Sequence<C>, C extends Compound> PairwiseSequenceAligner<S, C> getPairwiseAligner(
//            S query, S target, PairwiseAligner type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        switch (type) {
//        default:
//        case GLOBAL:
//            return new NeedlemanWunsch<S, C>(query, target, gapPenalty, subMatrix);
//        case LOCAL:
//            return new SmithWaterman<S, C>(query, target, gapPenalty, subMatrix);
//        case GLOBAL_LINEAR_SPACE:
//        case LOCAL_LINEAR_SPACE:
//            // TODO other alignment options (Myers-Miller, Thompson)
//            return null;
//        }
//    }
//
//    // constructs a pairwise sequence scorer
//    private static <S extends Sequence<C>, C extends Compound> PairwiseSequenceScorer<S, C> getPairwiseScorer(
//            S query, S target, PairwiseScorer type, GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        switch (type) {
//        default:
//        case GLOBAL:
//            return getPairwiseAligner(query, target, PairwiseAligner.GLOBAL, gapPenalty, subMatrix);
//        case GLOBAL_IDENTITIES:
//            return new FractionalIdentityScorer<S, C>(getPairwiseAligner(query, target, PairwiseAligner.GLOBAL, gapPenalty,
//                    subMatrix));
//        case GLOBAL_SIMILARITIES:
//            return new FractionalSimilarityScorer<S, C>(getPairwiseAligner(query, target, PairwiseAligner.GLOBAL, gapPenalty,
//                    subMatrix));
//        case LOCAL:
//            return getPairwiseAligner(query, target, PairwiseAligner.LOCAL, gapPenalty, subMatrix);
//        case LOCAL_IDENTITIES:
//            return new FractionalIdentityScorer<S, C>(getPairwiseAligner(query, target, PairwiseAligner.LOCAL, gapPenalty,
//                    subMatrix));
//        case LOCAL_SIMILARITIES:
//            return new FractionalSimilarityScorer<S, C>(getPairwiseAligner(query, target, PairwiseAligner.LOCAL, gapPenalty,
//                    subMatrix));
//        case KMERS:
//        case WU_MANBER:
//            // TODO other scoring options
//            return null;
//        }
//    }
//
//    // constructs a profile-profile aligner
//    private static <S extends Sequence<C>, C extends Compound> ProfileProfileAligner<S, C> getProfileProfileAligner(
//            Profile<S, C> profile1, Profile<S, C> profile2, ProfileAligner type, GapPenalty gapPenalty,
//            SubstitutionMatrix<C> subMatrix) {
//        switch (type) {
//        default:
//        case GLOBAL:
//            return new SimpleProfileProfileAligner<S, C>(profile1, profile2, gapPenalty, subMatrix);
//        case GLOBAL_LINEAR_SPACE:
//        case GLOBAL_CONSENSUS:
//        case LOCAL:
//        case LOCAL_LINEAR_SPACE:
//        case LOCAL_CONSENSUS:
//            // TODO other alignment options (Myers-Miller, consensus, local)
//            return null;
//        }
//    }
//
//    // constructs a profile-profile aligner
//    private static <S extends Sequence<C>, C extends Compound> ProfileProfileAligner<S, C> getProfileProfileAligner(
//            Future<ProfilePair<S, C>> profile1, Future<ProfilePair<S, C>> profile2, ProfileAligner type,
//            GapPenalty gapPenalty, SubstitutionMatrix<C> subMatrix) {
//        switch (type) {
//        default:
//        case GLOBAL:
//            return new SimpleProfileProfileAligner<S, C>(profile1, profile2, gapPenalty, subMatrix);
//        case GLOBAL_LINEAR_SPACE:
//        case GLOBAL_CONSENSUS:
//        case LOCAL:
//        case LOCAL_LINEAR_SPACE:
//        case LOCAL_CONSENSUS:
//            // TODO other alignment options (Myers-Miller, consensus, local)
//            return null;
//        }
//    }
//
//    // constructs a profile-profile aligner
//    private static <S extends Sequence<C>, C extends Compound> ProfileProfileAligner<S, C> getProfileProfileAligner(
//            Profile<S, C> profile1, Future<ProfilePair<S, C>> profile2, ProfileAligner type, GapPenalty gapPenalty,
//            SubstitutionMatrix<C> subMatrix) {
//        switch (type) {
//        default:
//        case GLOBAL:
//            return new SimpleProfileProfileAligner<S, C>(profile1, profile2, gapPenalty, subMatrix);
//        case GLOBAL_LINEAR_SPACE:
//        case GLOBAL_CONSENSUS:
//        case LOCAL:
//        case LOCAL_LINEAR_SPACE:
//        case LOCAL_CONSENSUS:
//            // TODO other alignment options (Myers-Miller, consensus, local)
//            return null;
//        }
//    }
//
//    // constructs a profile-profile aligner
//    private static <S extends Sequence<C>, C extends Compound> ProfileProfileAligner<S, C> getProfileProfileAligner(
//            Future<ProfilePair<S, C>> profile1, Profile<S, C> profile2, ProfileAligner type, GapPenalty gapPenalty,
//            SubstitutionMatrix<C> subMatrix) {
//        switch (type) {
//        default:
//        case GLOBAL:
//            return new SimpleProfileProfileAligner<S, C>(profile1, profile2, gapPenalty, subMatrix);
//        case GLOBAL_LINEAR_SPACE:
//        case GLOBAL_CONSENSUS:
//        case LOCAL:
//        case LOCAL_LINEAR_SPACE:
//        case LOCAL_CONSENSUS:
//            // TODO other alignment options (Myers-Miller, consensus, local)
//            return null;
//        }
//    }
//
//}
